home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 12 / Cream of the Crop 12 (Part II) / Cream of the Crop 12 (Part II).iso / OS2 / BLT2_205.ZIP / src / blt2cx07.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-18  |  13.8 KB  |  484 lines

  1. /* 
  2.  *
  3.  * blt2cx07.c - 17-Oct-1995 Cornel Huth
  4.  * This module is called by blt2demo.c
  5.  *
  6.  * Extend Bullet 2 file resources to the max by opening as many files as 
  7.  * possible (limited by version level so far as max files/max instances)
  8.  * Filenames generated are based on PID, and so multiple processes can
  9.  * be used without filename conflict.  It's recommended that this test be
  10.  * run in a new directory, for no reason other than that you can easily 
  11.  * delete the files created, all of which are of the form: $pidnnnn.DBF
  12.  * where pid is the process ID number, and nnnn is the sequence number
  13.  * of the file generated (0001, 0002, onward). (See below at "For Win95...").
  14.  *
  15.  * For non-multi-process versions (Bullet/X), no provision is made for
  16.  * more than one active process (other starts get a 'access denied' or
  17.  * 'file exists' message).
  18.  *
  19.  * No actual add operations are performed in this test (see a later example),
  20.  * but the create/open/close/delete operations are timed.  
  21.  *
  22.  * The mix of file types is one index file for each data file.  So, if the
  23.  * max files is 100, 50 DBFs and 50 index files are generated; if 250 files
  24.  * then 125/125; for 1024 files, 512 DBFs and 512 index files, though the
  25.  * actual number is determined by the number entered from the keyboard
  26.  * (i.e., the user) and also the DLL capability level -- the shareware 
  27.  * DLL has 100 files max, per process, with up to two processes active.
  28.  *
  29.  * ------------------------------------------------------------------------
  30.  * For Win95, VFAT file system, the limit is also like MS-DOS:  about 230
  31.  * files.  NT using NTFS or HPFS has no preset limit.  Also, Win95 seems to
  32.  * return the same PID for things run in an MS-DOS box.  This means that if
  33.  * you run this module simultaneously with another "files blowout" run, you 
  34.  * should do so in separate directories since the filenames generated are
  35.  * based on the PID, and if the PIDs are the same, so are the filenames.
  36.  * Also, you probably will only be able to open about 230 or so files, tops,
  37.  * on VFAT file systems (i.e., the Win95 file system).  This is the maximum
  38.  * *** TOTAL SYSTEM HANDLES *** in Win95/VFAT -- for everything that uses
  39.  * handles (semaphores, files, you name it!  only 255 of them system-wide).
  40.  *
  41.  * Bullet95.DLL can open and use up to 100 files at the same time, with up
  42.  * to two concurrent processes.
  43.  *
  44.  * -----------------------------------------------------------------------
  45.  * 
  46.  * For DOSX, the file limit is about 250, but is dependent on the FILES=
  47.  * statement in CONFIG.SYS.
  48.  *
  49.  * All files are open simultaneously, i.e., no files are closed until all 
  50.  * have been opened, after which all are closed and deleted.  The creates, 
  51.  * opens, and closes are all timed, individually, as well as the sum of all.
  52.  *
  53.  * Note: Since the process cannot easily know which files belong to it
  54.  *       from any previous run, and since there may be multiple processes
  55.  *       generating these files, this program deletes the files created
  56.  *       at the end of the run, rather than at the beginning as most other
  57.  *       examples do.
  58.  *
  59.  * Warning: For FAT file systems, the performance will suffer greatly
  60.  *          if a lot of files are requested (say, over 300).  This
  61.  *          because FAT requires a sequential search through the 
  62.  *          directory for file opens. (Re: OS/2 FAT, not Win95 VFAT.)
  63.  */
  64.  
  65. #include "platform.h"
  66.  
  67. #ifdef ON_OS2
  68.    #define INCL_DOSPROCESS // for OS/2 DosGetInfoBlocks
  69.    #include <os2.h>
  70. #endif
  71. #ifdef ON_W95
  72.    #define WIN32_LEAN_AND_MEAN
  73.    #include <windows.h>
  74. #endif
  75.  
  76. #include <stdio.h>
  77. #include <stdlib.h>
  78. #include <time.h>
  79. #include <string.h>
  80.  
  81. #ifdef ON_OS2
  82.    #include "bullet2.h"
  83. #endif
  84. #ifdef ON_W95
  85.    #include "bullet95.h"
  86. #endif
  87. #ifdef ON_DOSX
  88.    #include "bulletx.h"
  89. #endif
  90.  
  91. #ifdef ON_OS2
  92.    #define MAX_DATA_FILES 512   // your DLL/LIB may not be capable of allowing
  93.    #define MAX_INDEX_FILES 512  // as many as this (see your manual)
  94. #endif
  95. #ifdef ON_W95                   // if using NTFS or HPFS, can use more
  96.    #define MAX_DATA_FILES 512   // but VFAT (Win95) is limited to 230 or so
  97.    #define MAX_INDEX_FILES 512  // but NTFS or HPFS under NT can do many more
  98. #endif
  99. #ifdef ON_DOSX
  100.    #define MAX_DATA_FILES 125
  101.    #define MAX_INDEX_FILES 125
  102. #endif
  103.  
  104. void cx07BuildFieldList(FIELDDESCTYPE fieldList[]);
  105.  
  106. extern CHAR *collateTable;
  107.  
  108.  
  109. int cx07(void) {
  110.  
  111. #pragma pack(1)
  112.  
  113. DOSFILEPACK DFP;
  114. CREATEDATAPACK CDP;
  115. CREATEINDEXPACK CIP;
  116. HANDLEPACK HP;
  117. OPENPACK OP;
  118. QUERYSETPACK QSP;
  119.  
  120.  
  121. //struct EmpRecType {
  122. // CHAR tag;              // record tag, init to SPACE, * means deleted
  123. // CHAR empID[9];         // SSN (not 0T string)
  124. // CHAR empLN[16];        // last name
  125. // CHAR empFN[16];        // first name
  126. // CHAR empHire[8];       // "YYYYMMDD" (not 0T string)
  127. // CHAR empDept[6];       // department assigned
  128. //}; // 56 bytes
  129. //struct EmpRecType EmpRec;  // not used in this example
  130.  
  131. #pragma pack()
  132.  
  133. time_t startTime,endTime,endTime2,endTime3,endTime4,
  134.        endTime5,endTime6,endTime7,endTime8;
  135.  
  136. LONG rez;                       // return value from Bullet
  137. LONG i;                         // misc counter
  138.  
  139. LONG maxFiles;                  // max files DLL allows per process
  140. LONG userFiles;                 // number tester wants (up to maxFiles)
  141. LONG dataFiles;                 // computed number of data files (1/3rd)
  142. LONG indexFiles;                // computed number of index files (2/3rd)
  143.  
  144. #ifdef ON_OS2
  145.    PTIB pptib;                  // for DosGetInfoBlocks
  146.    PPIB pppib;                  // for DosGetInfoBlocks
  147.    CHAR sPID[4];                // this process ID, ASCII format (e.g.,"0015")
  148. #endif
  149. #ifdef ON_W95
  150.    DWORD PID;                   // process ID (low word only)
  151.    CHAR sPID[4];                // this process ID, ASCII format (e.g.,"0015")
  152. #endif
  153.  
  154. CHAR nameData[]="$pid#nnn.DBF"; // data filenames built here
  155. ULONG dataID[MAX_DATA_FILES]={0}; // handles of data files, max this test uses
  156. FIELDDESCTYPE fieldList[5];     // 5 fields used in data record (all use same)
  157.  
  158. CHAR nameIX3[]="$pid#nnn.IX3";  // index filenames built here
  159. ULONG indexID[MAX_INDEX_FILES]={0}; // handles of indexes, max this test uses
  160. CHAR keyExpression[128];        // key expression string buffer (all use same)
  161.  
  162. CHAR tmpStr[64];                // misc stuff, non-Bullet related
  163.  
  164. setbuf(stdout,NULL);
  165.  
  166. memset(fieldList,0,sizeof(fieldList));  // init unused bytes to 0 (required)
  167. cx07BuildFieldList(fieldList);
  168.  
  169. #ifdef ON_OS2
  170.    // get PID for unique filenames
  171.  
  172.    rez = DosGetInfoBlocks(&pptib,&pppib);
  173.    sprintf(sPID,"%4.4x",(pppib->pib_ulpid & 0xFFFF)); // pre-build filenames
  174.    strncpy(nameData+1,sPID,4);
  175.    strncpy(nameIX3+1,sPID,4);
  176. #endif
  177. #ifdef ON_W95
  178.    // get PID for unique filenames
  179.  
  180.    PID = GetCurrentProcessId();
  181.    sprintf(sPID,"%4.4x",(PID & 0xFFFF)); // pre-build filenames ($0001nnn.ext)
  182.    strncpy(nameData+1,sPID,4);
  183.    strncpy(nameIX3+1,sPID,4);
  184. #endif
  185.  
  186. // find out max files your DLL/LIB version has (100, 250, or 1024)
  187. // you'll already know this, but for this general purpose example...
  188.  
  189. QSP.func = QUERY_SYSVARS_XB;
  190. QSP.item = 28;
  191. rez = BULLET(&QSP);
  192. if (rez) {
  193.    printf("Failed QUERY_SYSVARS call.  Err: %li\n",rez);
  194.    goto Abend;
  195. }
  196. maxFiles = QSP.itemValue;
  197.  
  198. #ifdef ON_W95
  199.    printf("** For W95/VFAT: Max files that can be opened is about 230. **\n");
  200.    printf("** That is a SYSTEM-WIDE maximum, not per process.          **\n");
  201.    printf("** This includes all handles, not just file handles.        **\n");
  202. #endif
  203. #ifdef ON_DOSX
  204.    printf("For DOSX: Max files that can be opened is dependent on FILES= in CONFIG.SYS\n");
  205. #endif
  206. printf("Max files to generate (half data+half index)? (max %d): ",maxFiles);
  207. gets(tmpStr);
  208. userFiles = atol(tmpStr);
  209. if (userFiles > maxFiles) userFiles = maxFiles;
  210. if (userFiles < 2)        userFiles = 2;
  211.  
  212. dataFiles = userFiles >> 1; // half are data files
  213. indexFiles = dataFiles;     // and the other half index files
  214.  
  215. printf("Using %d data and %d index files for a total of %d files\n\n",
  216.         dataFiles,
  217.         indexFiles,
  218.         (dataFiles+indexFiles));
  219.  
  220. time(&startTime);
  221.  
  222. // Create the data file, a standard DBF (ID=3) as defined in fieldList above.
  223.  
  224. CDP.func = CREATE_DATA_XB;      // these are all invariant
  225. CDP.filenamePtr = nameData;     // all DBF files will be similar except in name
  226. CDP.noFields = 5;
  227. CDP.fieldListPtr = fieldList;
  228. CDP.fileID = 0x03;
  229.  
  230. for (i=1;i <= dataFiles;i++) {
  231.    
  232.    sprintf(tmpStr,"%3.3i",i);
  233.    strncpy(nameData+5,tmpStr,3);
  234.  
  235.    rez = BULLET(&CDP);
  236.    if (rez) {
  237.       printf("Failed data file #%i create.  Err: %li\n",i,rez);
  238.       goto Abend;
  239.    }
  240.    else
  241.       printf("Created: %d\r",i);
  242. }
  243.  
  244. time(&endTime);
  245. printf("Created: %d data files - took %lu secs.\n",i-1,(endTime - startTime));
  246.  
  247. // Open the data files
  248.  
  249. OP.func = OPEN_DATA_XB;
  250. OP.filenamePtr = nameData;
  251. OP.asMode = READWRITE | DENYNONE;
  252.  
  253. for (i=1;i <= dataFiles;i++) {
  254.    
  255.    sprintf(tmpStr,"%3.3i",i);
  256.    strncpy(nameData+5,tmpStr,3);
  257.  
  258.    rez = BULLET(&OP);
  259.    if (rez) {
  260.       printf("Failed data file #%i open.    Err: %li\n",i,rez);
  261.       if (rez==4)
  262.          printf("\nYou ran out of handles after %d handles.\n\n",i-1);
  263.       goto Abend;
  264.    }
  265.    else {
  266.       printf(" Opened: %d\r",i);
  267.       dataID[i-1]=OP.handle;
  268.    }
  269. }
  270. time(&endTime2);
  271. printf(" Opened: %d data files - took %lu secs.\n\n",i-1,(endTime2 - endTime));
  272.  
  273. // Create an index file for each data file.
  274. // All index files are the same, except for name, for this example
  275.  
  276. strcpy(keyExpression,"SSN");
  277.  
  278. CIP.func = CREATE_INDEX_XB;
  279. CIP.filenamePtr = nameIX3;
  280. CIP.keyExpPtr = keyExpression;
  281. CIP.sortFunction = NLS_SORT;
  282. CIP.codePage = CODEPAGE;
  283. CIP.countryCode = CTRYCODE;
  284. CIP.collatePtr = collateTable;
  285. CIP.nodeSize = 512;
  286.  
  287. for (i=1;i <= indexFiles;i++) {
  288.    
  289.    sprintf(tmpStr,"%3.3i",i);
  290.    strncpy(nameIX3+5,tmpStr,3);
  291.  
  292.    CIP.xbLink = dataID[i-1];    // its cooresponding DBF handle
  293.    rez = BULLET(&CIP);
  294.    if (rez) {
  295.       printf("Failed index file #%i create.  Err: %li\n",i,rez);
  296.       goto Abend;
  297.    }
  298.    else
  299.       printf("Created: %d\r",i);
  300. }
  301.  
  302. time(&endTime3);
  303. printf("Created: %d index files- took %lu secs.\n",i-1,(endTime3 - endTime2));
  304.  
  305. // Open the index files
  306.  
  307. OP.func = OPEN_INDEX_XB;
  308. OP.filenamePtr = nameIX3;
  309. OP.asMode = READWRITE | DENYNONE;
  310.  
  311. for (i=1;i <= indexFiles;i++) {
  312.    
  313.    sprintf(tmpStr,"%3.3i",i);
  314.    strncpy(nameIX3+5,tmpStr,3);
  315.  
  316.    OP.xbLink = dataID[i-1];     // its cooresponding DBF handle
  317.    rez = BULLET(&OP);
  318.    if (rez) {
  319.       printf("Failed index file #%i open.    Err: %li\n",i,rez);
  320.       if (rez==4)
  321.          printf("\nYou ran out of handles after %d handles.\n\n",dataFiles+i-1);
  322.       goto Abend;
  323.    }
  324.    else {
  325.       printf(" Opened: %d\r",i);
  326.       indexID[i-1]=OP.handle;
  327.    }
  328. }
  329. time(&endTime4);
  330. printf(" Opened: %d index files- took %lu secs.\n\n",i-1,(endTime4 - endTime3));
  331.  
  332.  
  333. // Abnormal endings come here
  334. Abend:
  335.  
  336. if (rez) time(&endTime4);
  337.  
  338. // Close the index files
  339.  
  340. HP.func = CLOSE_INDEX_XB;
  341. for (i=1;i <= indexFiles;i++) {
  342.    if (indexID[i-1]) {
  343.       HP.handle = indexID[i-1];
  344.       rez = BULLET(&HP);
  345.       if (rez)
  346.          printf("Failed index file #%i close.   Err: %li\n",i,rez);
  347.       else {
  348.          printf(" Closed: %d\r",i);
  349.          indexID[i-1]=0;
  350.       }
  351.    }
  352. }
  353. time(&endTime5);
  354. printf(" Closed: %d index files- took %lu secs.\n",i-1,(endTime5 - endTime4));
  355.  
  356. // Close the data files (only closes if handle != 0)
  357.  
  358. HP.func = CLOSE_DATA_XB;
  359. for (i=1;i <= dataFiles;i++) {
  360.    if (dataID[i-1]) {
  361.       HP.handle = dataID[i-1];
  362.       rez = BULLET(&HP);
  363.       if (rez)
  364.          printf("Failed data file #%i close.   Err: %li\n",i,rez);
  365.       else {
  366.          printf(" Closed: %d\r",i);
  367.          dataID[i-1]=0;
  368.       }
  369.    }
  370. }
  371. time(&endTime6);
  372. printf(" Closed: %d data files - took %lu secs.\n\n",i-1,(endTime6 - endTime5));
  373.  
  374. // Delete the index files
  375.  
  376. DFP.func = DELETE_FILE_DOS;
  377. DFP.filenamePtr = nameIX3;
  378. for (i=1;i <= indexFiles;i++) {
  379.    
  380.    sprintf(tmpStr,"%3.3i",i);
  381.    strncpy(nameIX3+5,tmpStr,3);
  382.  
  383.    rez = BULLET(&DFP);
  384.    if (rez) {
  385.       printf("Failed index file #%i delete.  Err: %li\n",i,rez);
  386.    }
  387.    else
  388.       printf("Deleted: %d index files\r",i);
  389. }
  390. time(&endTime7);
  391. printf("Deleted: %d index files- took %lu secs.\n",i-1,(endTime7 - endTime6));
  392.  
  393. // Delete the data files
  394.  
  395. DFP.func = DELETE_FILE_DOS;
  396. DFP.filenamePtr = nameData;
  397. for (i=1;i <= dataFiles;i++) {
  398.    
  399.    sprintf(tmpStr,"%3.3i",i);
  400.    strncpy(nameData+5,tmpStr,3);
  401.  
  402.    rez = BULLET(&DFP);
  403.    if (rez) {
  404.       printf("Failed data file #%i delete.  Err: %li\n",i,rez);
  405.    }
  406.    else
  407.       printf("Deleted: %d data files\r",i);
  408. }
  409. time(&endTime8);
  410. printf("Deleted: %d data files - took %lu secs.\n\n",i-1,(endTime8 - endTime7));
  411.  
  412. printf("Total time: %d seconds.\n",(endTime8 - startTime));
  413. return rez;  // module exit
  414. }
  415.  
  416.  
  417. //------------------------------------
  418. // Init field list items for data file
  419.  
  420. void cx07BuildFieldList(FIELDDESCTYPE fieldList[]) {
  421.  
  422. strcpy(fieldList[0].fieldName, "SSN");  // field names must be upper-case
  423. fieldList[0].fieldType = 'C';           // field types must be upper-case
  424. fieldList[0].fieldLen = 9;
  425. fieldList[0].fieldDC = 0;
  426.  
  427. strcpy(fieldList[1].fieldName, "LNAME");
  428. fieldList[1].fieldType = 'C';
  429. fieldList[1].fieldLen = 16;
  430. fieldList[1].fieldDC = 0;
  431.  
  432. strcpy(fieldList[2].fieldName, "FNAME");
  433. fieldList[2].fieldType = 'C';
  434. fieldList[2].fieldLen = 16;
  435. fieldList[2].fieldDC = 0;
  436.  
  437. strcpy(fieldList[3].fieldName, "HIRED");
  438. fieldList[3].fieldType = 'D';
  439. fieldList[3].fieldLen = 8;      // date field type must be 8.0
  440. fieldList[3].fieldDC = 0;
  441.  
  442. strcpy(fieldList[4].fieldName, "DEPT");
  443. fieldList[4].fieldType = 'C';
  444. fieldList[4].fieldLen = 6;
  445. fieldList[4].fieldDC = 0;
  446. }
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.